package cn.ibizlab.util.web;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ObjectUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class IpPatternMatcher {

    private static final Logger log = LoggerFactory.getLogger(IpPatternMatcher.class);

    /**
     * 将带有通配符的 IP 地址模式转换为正则表达式。
     *
     * @param pattern 带有通配符的 IP 地址模式
     * @return 正则表达式字符串
     */
    private String convertToRegex(String pattern) {
        return "^" + pattern.replace(".", "\\.")
                            .replace("*", "[0-9]{1,3}") + "$";
    }

    /**
     * 检查给定的 IP 地址是否匹配指定的模式。
     *
     * @param ipAddress 要检查的 IP 地址
     * @param pattern   IP 地址模式
     * @return 如果匹配，则返回 true；否则返回 false。
     */
    public boolean matches(String ipAddress, String pattern) {
        if (ipAddress == null || pattern == null) {
            return false;
        }
        // 如果没有通配符，直接比较字符串
        if (!pattern.contains("*")) {
            return ipAddress.equals(pattern);
        }
        // 否则使用正则表达式匹配
        return Pattern.matches(convertToRegex(pattern), ipAddress);
    }

    private Set<String> allowedIps;

    private static Map<String,IpPatternMatcher> instance = new HashMap<>();

    public static synchronized IpPatternMatcher getInstance(String allowedIpsStr) {
        if(instance.containsKey(allowedIpsStr))
            return instance.get(allowedIpsStr);

        IpPatternMatcher matcher = new IpPatternMatcher();
        // 将逗号分隔的字符串转换为集合，并去除空格
        matcher.allowedIps = Arrays.stream(allowedIpsStr.split(","))
                .map(String::trim)
                .filter(s -> !s.isEmpty())
                .collect(Collectors.toSet());
        instance.put(allowedIpsStr, matcher);
        return matcher;
    }


    public boolean isIpAllowed(String ipAddress) {
        if (ObjectUtils.isEmpty(allowedIps))
            return true;
        if (ipAddress == null)
            ipAddress = IPUtils.getIpAddr(null);
        for (String pattern : allowedIps) {
            if (matches(ipAddress, pattern)) {
                return true;
            }
        }
        log.error(ipAddress+"限制访问");
        return false;
    }
}